feat: restore working tree when release fails locally#205
Merged
Conversation
There was a problem hiding this comment.
Pull request overview
This PR introduces a rollback mechanism that restores the local git working tree (and related git objects) when a release fails locally, and adds a --no-rollback escape hatch. It integrates rollback snapshotting into stage execution and finalizes rollback after the release run ends.
Changes:
- Add rollback snapshot + finalize lifecycle in
@alcalzone/release-script-core(stash snapshot, HEAD reset, optional tag deletion, untracked cleanup). - Wire rollback into execution flow: snapshot before first mutating stage; finalize rollback at the end of the CLI run.
- Track git-side rollback state in the git plugin (created tag and whether push was attempted), with added tests.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/release-script/src/index.ts | Adds --noRollback option and ensures rollback finalization runs before exiting on failures. |
| packages/plugin-git/src/index.ts | Records created tag for safe deletion and marks when push begins to disable rollback after remote interaction. |
| packages/plugin-git/src/index.test.ts | Adds tests around rollback.pushAttempted behavior in push stage. |
| packages/core/src/types.ts | Exports RollbackState type from core types. |
| packages/core/src/lib/rollback.ts | Implements rollback snapshotting and finalization logic using git commands and stash bookkeeping. |
| packages/core/src/lib/rollback.test.ts | Adds unit tests for rollback snapshot/finalize behavior. |
| packages/core/src/lib/planner.ts | Captures rollback snapshot before the first non-check stage executes. |
| packages/core/src/lib/context.ts | Extends Context with optional rollback state and defines RollbackState. |
| packages/core/src/index.ts | Exports rollback functions from core public API. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+100
to
+103
| context.cli.warn( | ||
| `Failed to snapshot uncommitted changes for rollback: ${e?.message ?? e}. ` + | ||
| `Rollback will undo committed and edited files but cannot restore ` + | ||
| `untracked files; cleanup of untracked files will be skipped.`, |
|
|
||
| /** | ||
| * State used to roll back local changes if the release fails. | ||
| * Populated by `captureRollbackSnapshot` once the edit stage is about to run. |
Comment on lines
+70
to
+80
| // Conservatively treat the tree as dirty so rollback won't run a | ||
| // destructive `git clean` against state we couldn't observe. | ||
| context.cli.warn( | ||
| `Could not determine working tree status for rollback: ${e?.message ?? e}. ` + | ||
| `Rollback will skip cleanup of untracked files to avoid data loss.`, | ||
| ); | ||
| context.rollback = { | ||
| originalHead, | ||
| pushAttempted: false, | ||
| cleanAllowedDuringRollback: false, | ||
| }; |
| context.rollback = { | ||
| originalHead: "deadbeef", | ||
| pushAttempted: false, | ||
| cleanAllowedDuringRollback: true, |
Comment on lines
+466
to
+470
| context.rollback = { | ||
| originalHead: "deadbeef", | ||
| pushAttempted: false, | ||
| cleanAllowedDuringRollback: true, | ||
| }; |
Comment on lines
+490
to
+494
| context.rollback = { | ||
| originalHead: "deadbeef", | ||
| pushAttempted: false, | ||
| cleanAllowedDuringRollback: true, | ||
| }; |
Comment on lines
+509
to
+513
| context.rollback = { | ||
| originalHead: "deadbeef", | ||
| pushAttempted: false, | ||
| cleanAllowedDuringRollback: true, | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
supersedes: #118